home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
dev
/
c
/
AmiVoGL_MDEV.lha
/
drivers
/
decX11.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-15
|
12KB
|
581 lines
/*
* VOGLE driver for X11 under the DEC window manager.
*
* ok so we admit that we don't know heaps about X11, but come
* on guys, this shouldn't be neccessary (wild comment from DEC about
* why our standard X11 driver won't work is welcome.)
*/
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "vogl.h"
#define LARGEX11R2 "courier12f.snf"
#define SMALLX11R2 "courier10f.snf"
#define LARGEX11R3 "-adobe-courier-medium-r-normal--24-240-75-75-m-150-iso8859-1"
#define SMALLX11R3 "-adobe-courier-medium-r-normal--10-100-75-75-m-60-iso8859-1"
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#define CMAPSIZE 256
#define EV_MASK KeyPressMask|ButtonReleaseMask|ExposureMask|ButtonPressMask
static Window winder;
static Display *display;
static int screen;
static unsigned long carray[CMAPSIZE];
static Colormap colormap;
static Drawable theDrawable;
static GC theGC;
static Pixmap bbuf; /* Back buffer pixmap */
static int back_used; /* Have we backbuffered ? */
static XFontStruct *font_id;
XEvent event;
static int size;
static unsigned long colour;
static unsigned int h, w;
/*
* DECX11_init
*
* initialises X11 display.
*/
int DECX11_init(void)
{
int i;
int x, y, prefx, prefy, prefxs, prefys;
unsigned int bw, depth, mask;
Window rootw, childw, topwinder, *kiddies;
char *av[2], name[50];
XSetWindowAttributes theWindowAttributes;
XSizeHints theSizeHints;
unsigned long theWindowMask;
XWMHints theWMHints;
av[0] = "vogl.X11";
av[1] = (char *)NULL;
if ((display = XOpenDisplay((char *)NULL)) == (Display *)NULL) {
fprintf(stderr,"vogl: DECX11_init: can't connect to X server\n");
exit(1);
}
winder = DefaultRootWindow(display);
screen = DefaultScreen(display);
vdevice.depth = DefaultDepth(display, screen);
colormap = DefaultColormap(display, screen);
/*
* Set our standard colors...
*/
if (vdevice.depth == 1) {
/*
* Black and white - anything that's not black is white.
*/
carray[0] = BlackPixel(display, screen);
for (i = 1; i < CMAPSIZE; i++)
carray[i] = WhitePixel(display, screen);
} else {
/*
* Color, try to get our colors close to what's in the
* default colormap.
*/
DECX11_mapcolor(0, 0, 0, 0);
DECX11_mapcolor(1, 255, 0, 0);
DECX11_mapcolor(2, 0, 255, 0);
DECX11_mapcolor(3, 255, 255, 0);
DECX11_mapcolor(4, 0, 0, 255);
DECX11_mapcolor(5, 255, 0, 255);
DECX11_mapcolor(6, 0, 255, 255);
DECX11_mapcolor(7, 255, 255, 255);
}
getprefposandsize(&prefx, &prefy, &prefxs, &prefys);
XQueryPointer(display, winder, &rootw, &childw, &x, &y, &x, &y, &mask);
if (childw == None)
childw = rootw;
/*
* there is something very weird about dec's window manager
* as expressed on a dec station, to get the details for the window
* we are actually in we have to get the root window of the childw
* which gives us the root window of the real window stack, and then
* we use XQueryPointer to find the real child window.
*/
XQueryTree(display, childw, &rootw, &rootw, &kiddies, &i);
topwinder = winder;
winder = kiddies[0];
XQueryPointer(display, winder, &rootw, &childw, &x, &y, &x, &y, &mask);
XGetGeometry(display, childw, &rootw, &x, &y, &w, &h, &bw, &depth);
if (prefx > -1) {
x = prefx;
y = prefy;
}
if (prefxs > -1) {
w = prefxs;
h = prefys;
}
x += bw;
y += bw;
w -= 2 * bw;
h -= 2 * bw;
theWindowAttributes.override_redirect = False;
/*theWindowMask = CWBackPixel|CWBorderPixel|CWOverrideRedirect;*/
theWindowMask = CWOverrideRedirect;
winder = XCreateWindow(display,
topwinder,
x, y,
w, h,
bw,
(int)depth,
InputOutput,
CopyFromParent,
theWindowMask,
&theWindowAttributes
);
theWMHints.initial_state = NormalState;
theWMHints.flags = StateHint;
XSetWMHints(display, winder, &theWMHints);
theSizeHints.flags = PPosition|PSize;
theSizeHints.x = x;
theSizeHints.y = y;
theSizeHints.width = w;
theSizeHints.height = h;
XSetNormalHints(display, winder, &theSizeHints);
sprintf(name, "vogl %d", getpid());
XSetStandardProperties(display,
winder,
name,
name,
None,
av,
1,
&theSizeHints
);
XSelectInput(display, winder, EV_MASK);
theDrawable = (Drawable)winder;
/*
* Let VOGLE know about the window size.
*/
vdevice.sizeX = vdevice.sizeY = MIN(h, w) - 1;
vdevice.sizeSx = w - 1;
vdevice.sizeSy = h - 1;
/*
* Create Graphics Context and Drawable
*/
theGC = XDefaultGC(display, screen);
theDrawable = (Drawable)winder;
DECX11_color(0);
XMapRaised(display, winder);
XFlush(display);
/*
* Wait for Exposure event.
*/
do {
XNextEvent(display, &event);
} while (event.type != Expose);
if (prefx == -1 && prefxs == -1)
XSetInputFocus(display, winder, RevertToParent, CurrentTime);
back_used = 0;
return(1);
}
/*
* DECX11_exit
*
* cleans up before returning the window to normal.
*/
int DECX11_exit(void)
{
XFreeGC(display, theGC);
if (back_used)
XFreePixmap(display, bbuf);
XUnmapWindow(display, winder);
XDestroyWindow(display, winder);
return(1);
}
/*
* DECX11_draw
*
* draws a line from the current graphics position to (x, y).
*
* Note: (0, 0) is defined as the top left of the window in X (easy
* to forget).
*/
int DECX11_draw(
int x,
int y)
{
XDrawLine(display,
theDrawable,
theGC,
vdevice.cpVx, vdevice.sizeSy - vdevice.cpVy,
x, vdevice.sizeSy - y
);
XFlush(display);
}
/*
* DECX11_getkey
*
* grab a character from the keyboard - blocks until one is there.
*/
int DECX11_getkey(void)
{
char c;
do {
XNextEvent(display, &event);
if (event.type == KeyPress) {
if (XLookupString(&event, &c, 1, NULL, NULL) > 0)
return((int)c);
else
return(0);
}
} while (event.type != KeyPress);
}
/*
* DECX11_checkkey
*
* Check if there has been a keyboard key pressed.
* and return it if there is.
*/
int DECX11_checkkey(void)
{
char c;
int i;
if (!XCheckWindowEvent(display, winder, KeyPressMask, &event))
return(0);
if (event.type == KeyPress)
if (XLookupString(&event, &c, 1, NULL, NULL) > 0)
return((int)c);
return(0);
}
/*
* DECX11_locator
*
* return the window location of the cursor, plus which mouse button,
* if any, is been pressed.
*/
int DECX11_locator(
int *wx,
int *wy)
{
Window rootw, childw;
int x, y, mask;
XQueryPointer(display, winder, &rootw, &childw, &x, &y, wx, wy, &mask);
*wy = (int)vdevice.sizeSy - *wy;
return(mask >> 8);
}
/*
* DECX11_clear
*
* Clear the screen (or current buffer )to current colour
*/
int DECX11_clear(void)
{
XSetBackground(display, theGC, colour);
XFillRectangle(display,
theDrawable,
theGC,
vdevice.minVx,
vdevice.minVy,
(unsigned int)vdevice.maxVx,
(unsigned int)vdevice.maxVy
);
}
/*
* DECX11_color
*
* set the current drawing color index.
*/
int DECX11_color(int ind)
{
colour = carray[ind];
XSetForeground(display, theGC, colour);
}
/*
* DECX11_mapcolor
*
* change index i in the color map to the appropriate r, g, b, value.
*/
int DECX11_mapcolor(
int i,
int r,
int g,
int b)
{
int stat;
XColor tmp;
if (i >= CMAPSIZE)
return(-1);
/*
* For Black and White.
* If the index is 0 and r,g,b != 0 then we are remapping black.
* If the index != 0 and r,g,b == 0 then we make it black.
*/
if (vdevice.depth == 1) {
if (i == 0 && (r != 0 || g != 0 || b != 0))
carray[i] = WhitePixel(display, screen);
else if (i != 0 && r == 0 && g == 0 && b == 0)
carray[i] = BlackPixel(display, screen);
} else {
tmp.red = (unsigned short)(r / 255.0 * 65535);
tmp.green = (unsigned short)(g / 255.0 * 65535);
tmp.blue = (unsigned short)(b / 255.0 * 65535);
tmp.flags = 0;
tmp.pixel = (unsigned long)i;
if ((stat = XAllocColor(display, colormap, &tmp)) =